extern crate test_macro;
use test_macro::{deco, my_log, retry, AnswerFn, Hello, PrintLog};

#[derive(Hello, AnswerFn, PrintLog)]
struct Test1;

#[retry(times = 3, timeout = 30)]
fn remote_request(a: i32, b: i32) -> i32 {
    println!("@remote_request!");
    a + b
}

#[deco(logging)]
fn add2(a: i32) -> i32 {
    a + 2
}

#[my_log]
fn add_two_numbers(a: i32, b: i32) -> i32 {
    a + b
}

/// decorator function
fn logging<F>(func: F) -> impl Fn(i32) -> i32
where
    F: Fn(i32) -> i32,
{
    move |x| {
        println!("Input: {}", x);
        let result = func(x);
        println!("Output: {}", result);
        result
    }
}

#[test]
fn derive_pass() {
    Test1::hello();
    assert_eq!(answer(), 42);
}

#[test]
fn test_print_log() {
    Test1::print_log();
    Test1::print_attrs();
}

#[test]
fn test_attr_macro() {
    remote_request(10, 22);
}

#[test]
fn test_deco_macro() {
    add2(3);
}

#[test]
fn test_my_log_macro() {
    assert_eq!(add_two_numbers(2, 3), 5);
}
